//
//  ERProperty.m
//  metadata
//
//  Created by easy on 11-5-30.
//  Copyright 2011 zeasy@qq.com. All rights reserved.
//

#import "ERProperty.h"
#import "ERClass.h"
#import "ERClassType.h"
#import "ERMethod.h"
#import "ERField.h"
@implementation ERProperty
@synthesize clazz;
@synthesize source;
@synthesize name;
@synthesize attributes;
@synthesize classType;
@synthesize mappedField;
@synthesize setterMethod;
@synthesize getterMethod;

#pragma mark init
-(id) initWithProperty:(objc_property_t) prop atERClass:(ERClass *) aClazz{
	if (self = [super init]) {
		clazz = aClazz;
		source = prop;
		NSString *aName = ER_STRING_ALLOC(property_getName(source));
		name = [aName retain];
		[aName release];
		NSString *attr = ER_STRING_ALLOC(property_getAttributes(source));
		attributes = [attr retain];
		[attr release];
		readWrite = READ_WRITE;
		assignment = ASSIGN;
		atomicity = ATOMIC;
		if (attributes != nil) {
			[self analysisAttributes];
		}
	}
	return self;
}

#pragma mark attributes 分析
-(void) analysisAttributes{//分析特性
	NSArray *arr = [attributes componentsSeparatedByString:@","];
	
	BOOL hasV = NO;
	BOOL hasG = NO;
	BOOL hasS = NO;
	for (NSString *str in arr) {
		NSString *s = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
		char type = [s characterAtIndex:0];
		switch (type) {
			case ER_PROPERTY_TYPE:
				classType = [[ERClassType alloc] initWithType:[s substringFromIndex:1]];
				break;
			case ER_PROPERTY_FIELD:
				hasV = YES;
				//fieldName = [[s substringFromIndex:1] retain];
				mappedField = [[self.clazz instanceFieldWithName:[s substringFromIndex:1]] retain];
				break;
			case ER_PROPERTY_GETTER:
				hasG = YES;
				getterMethod = [[self.clazz instanceMethodWithName:[s substringFromIndex:1]] retain];
				break;
			case ER_PROPERTY_SETTER:
				hasS = YES; 
				setterMethod = [[self.clazz instanceMethodWithName:[s substringFromIndex:1]] retain];
				break;
			case ER_PROPERTY_READ_ONLY:
				readWrite = READ_ONLY;
				break;
			case ER_PROPERTY_RETAIN:
				assignment = RETAIN;
				break;
			case ER_PROPERTY_COPY:
				assignment = COPY;
				break;
			case ER_PROPERTY_NONATOMIC: 
				atomicity = NONATOMIC;
				break;
		}
	}
	if (!hasV) {
		mappedField = [[self.clazz instanceFieldWithName:self.name] retain];
	}
	if (!hasS) {
		NSMutableString *str = [[NSMutableString alloc] initWithString:@"set"];
		[str appendString:[[self.name substringToIndex:1] capitalizedString]];
		[str appendString:[self.name substringFromIndex:1]];
		[str appendString:@":"];
		setterMethod = [[self.clazz instanceMethodWithName:str] retain];
		[str release];
	}
	if (!hasG) {
		getterMethod = [[self.clazz instanceMethodWithName:self.name] retain];
	}
}
-(BOOL) isReadOnly{//只读
	return readWrite == READ_ONLY;
}
-(BOOL) isReadWrite{//可读写
	return readWrite == READ_WRITE;
}
-(BOOL) isAssign{//仅赋值
	return assignment == ASSIGN;
}
-(BOOL) isRetain{//计数加一，拥有对象
	return assignment == RETAIN;
}
-(BOOL) isCopy{//复制对象
	return assignment == COPY;
}
-(BOOL) isAtomic{//原子性
	return atomicity == ATOMIC;
}
-(BOOL) isNonatomic{//非原子性
	return atomicity == NONATOMIC;
}


-(void) dealloc{ 
	source = nil; 
	[name release];
	[attributes release];
	[classType release];
	[mappedField release];
	[getterMethod release];
	[setterMethod release];
	[super dealloc];
}
@end
